package cn.cxq.learning.math;

import org.junit.jupiter.api.Test;

/**
 * 剑指offer
 * 二进制中1的个数
 * 时间限制：C/C++ 1秒，其他语言2秒 空间限制：C/C++ 64M，其他语言128M 热度指数：749213
 * 本题知识点： 数学
 *  算法知识视频讲解
 * 题目描述
 * 输入一个整数，输出该数32位二进制表示中1的个数。其中负数用补码表示。
 * 示例1
 * 输入
 * 复制
 * 10
 * 返回值
 * 复制
 * 2
 */
public class NumOfOne {

    @Test
    public void testNumberOf1() {
        System.out.println(NumberOf1(-2));
    }

    //采用简单的移位和与运算。
    /**
     * Java＞＞与＞＞＞的区别
     * >>：带符号右移。正数右移高位补0，负数右移高位补1。比如：
     * 4 >> 1，结果是2；-4 >> 1，结果是-2。-2 >> 1，结果是-1。
     * >>>：无符号右移。无论是正数还是负数，高位通通补0。
     * 对于正数而言，>>和>>>没区别。
     * 对于负数而言，-2 >>> 1，结果是2147483647（Integer.MAX_VALUE），-1 >>> 1，结果是2147483647（Integer.MAX_VALUE）。
     * 以下代码可以判断两个数的符号是否相等
     * return ((a >> 31) ^ (b >> 31)) == 0;
     * @param n
     * @return
     */
    public int NumberOf1(int n) {

        int sum = 0;

        for (int i = 0; i < 32; i++) {
            int temp = n & 1;
            if (temp == 1) {
                sum++;
            }
            n >>= 1;
        }

        return sum;
    }

    // 使用库函数
//    public int NumberOf1(int n) {
//
//        int sum = 0;
//
//        String binaryString = Integer.toBinaryString(n);
//
//        for (int i = 0; i < binaryString.length(); i++) {
//            if (binaryString.charAt(i) == '1') {
//                sum++;
//            }
//        }
//        return sum;
//    }
}
